// 实现登录访问控制的逻辑 => 守卫是给router加的
import router, { asyncRoutes } from '@/router'
import store from './store'
// 下载好了 => 导入2个 => start/done
import NProgress from 'nprogress'
import 'nprogress/nprogress.css' // 样式导入进来

const WHITE_LIST = ['/login', '/404']
// console.log(WHITE_LIST)

/*
  专业的守卫

     判断有无token

        有token 判断是否去登录页
            是去登录页      拦截去首页
            不是去登录页    直接放行

        无token 判断是否去白名单页面
            是去白名单      直接放行
            不是去白名单    拦截去登录
*/
router.beforeEach(async(to, from, next) => {
  // 任何一个页面在解析渲染之前 都会经过前置守卫 立马开启进度条 => 后置守卫
  NProgress.start()

  if (store.getters.token) {
    if (to.path === '/login') {
      next('/')
      NProgress.done() // 手动关闭
    } else {
      // 请求用户数据
      // 分析:
      // 1. 获取用户数据必须需要token作为请求头的 => 肯定得确保有token
      // 2. 将来我想进入系统内查看页面 在那之前就应该获取到用户数据  再放行!!!
      if (!store.state.user.userInfo.userId) {
        // 只要发现userInfo是空对象 说明没获取过信息 就可以获取一下信息(menus)
        const res = await store.dispatch('user/getUserInfoAction')
        console.log('用户的menus', res.roles.menus)

        // 根据menus动态添加对应的规则   router.addRoutes([{}, {}, ....])
        const temp = asyncRoutes.filter(item => {
          // return true // 全留下来了
          // return false // 一个不留
          // 过滤的这个函数如果返回值是true 表示item这项会保留
          // 过滤的这个函数如果返回值是false 表示item这项会删除
          // console.log(item)
          return res.roles.menus.includes(item.children[0].name)
        }) // 过滤了个寂寞
        console.log('过滤后的规则', temp)

        // 过滤出来的路由规则需要更新到user仓库中的routes
        store.commit('user/setRoutes', temp)

        // 过渡的需求: 请你帮我动态添加8个动态路由规则(我不需要你根据menus)
        // 只要前面登录的人足够多 最后一个登录的人 就拥有前面所有人的规则！！！ => router是唯一的!! 在不停地加规则
        // 讲道理  一个用户登出系统了, 项目中唯一的路由实例router要不要重置成初始规则(3个静态规则) => 退出的时候(action) 重置规则
        router.addRoutes([...temp, { path: '*', redirect: '/404', hidden: true }]) // 临时添加了8个动态路由规则(如果是调用addRoutes添加的规则不会立即生效的-已知缺陷)
        // 有一个配套的固定的方案可以解决
        next(to.path) // 重新进一次页面 确保刚刚添加的规则生效
        return
      }

      next()
    }
  } else {
    if (WHITE_LIST.includes(to.path)) {
      next()
    } else {
      next('/login')
      NProgress.done() // 手动关闭
    }
  }
})

// 细节: 任何页面被解析渲染之后 确实都会经过后置守卫; 有一种特殊情况 不会经过后置守卫 => 被拦截走了
// 解决: 被拦截走的 手动关闭进度条
router.afterEach((to, from) => {
  // 任何一个页面在解析渲染之后 都会经过后置守卫 => 页面已经看到了 页面已经被放行了 没有next
  NProgress.done()
})
